package loaders

import (
	"context"
	"io/ioutil"
	"path/filepath"
	"strings"
	"time"

	"github.com/yuin/goldmark"
	"github.com/yuin/goldmark/ast"
	"github.com/yuin/goldmark/text"
)

// MarkdownLoader Markdown文件加载器
type MarkdownLoader struct {
	*BaseLoader
	ExtractFrontmatter bool
}

// NewMarkdownLoader 创建Markdown文件加载器
func NewMarkdownLoader(filePath string) *MarkdownLoader {
	return &MarkdownLoader{
		BaseLoader:         NewBaseLoader(filePath),
		ExtractFrontmatter: true,
	}
}

// Load 加载Markdown文件
func (l *MarkdownLoader) Load(ctx context.Context) ([]Document, error) {
	startTime := time.Now()
	l.logInfo("开始加载Markdown文件")

	// 读取文件内容
	content, err := ioutil.ReadFile(l.FilePath)
	if err != nil {
		l.logError(err, "读取Markdown文件失败")
		return nil, err
	}

	// 提取纯文本内容
	extractedContent := l.extractTextFromMarkdown(string(content))

	// 创建文档对象
	doc := Document{
		Content: extractedContent,
		MetaData: map[string]interface{}{
			"file_path":    l.FilePath,
			"file_name":    filepath.Base(l.FilePath),
			"file_ext":     "md",
			"content_type": "text/markdown",
			"loader_type":  "MarkdownLoader",
			"load_time":    startTime.Format(time.RFC3339),
			"content_size": len(extractedContent),
		},
		FilePath: l.FilePath,
	}

	// 尝试提取frontmatter
	if l.ExtractFrontmatter {
		frontmatter := l.extractFrontmatter(string(content))
		if len(frontmatter) > 0 {
			doc.MetaData["frontmatter"] = frontmatter
		}
	}

	l.logInfo("Markdown文件加载成功", map[string]interface{}{
		"content_size": len(extractedContent),
		"load_time_ms": time.Since(startTime).Milliseconds(),
	})

	return []Document{doc}, nil
}

// extractTextFromMarkdown 从Markdown提取纯文本
func (l *MarkdownLoader) extractTextFromMarkdown(markdown string) string {
	source := []byte(markdown)
	reader := text.NewReader(source)
	md := goldmark.New()
	parser := md.Parser()
	node := parser.Parse(reader)

	var textBuilder strings.Builder
	ast.Walk(node, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
		if entering {
			if n.Kind() == ast.KindText {
				t := n.(*ast.Text)
				textBuilder.WriteString(string(t.Text(source)))
				textBuilder.WriteString(" ")
			}
		}
		return ast.WalkContinue, nil
	})

	result := textBuilder.String()
	// 清理多余的空格和换行
	result = strings.ReplaceAll(result, "\n", " ")
	for strings.Contains(result, "  ") {
		result = strings.ReplaceAll(result, "  ", " ")
	}

	return strings.TrimSpace(result)
}

// extractFrontmatter 提取Markdown frontmatter
func (l *MarkdownLoader) extractFrontmatter(markdown string) map[string]interface{} {
	result := make(map[string]interface{})

	lines := strings.Split(markdown, "\n")
	if len(lines) < 3 {
		return result
	}

	// 检查是否有YAML frontmatter
	if strings.TrimSpace(lines[0]) == "---" {
		var frontmatterLines []string
		for i := 1; i < len(lines); i++ {
			if strings.TrimSpace(lines[i]) == "---" {
				break
			}
			frontmatterLines = append(frontmatterLines, lines[i])
		}

		if len(frontmatterLines) > 0 {
			result["raw"] = strings.Join(frontmatterLines, "\n")
			// 简单解析key-value
			for _, line := range frontmatterLines {
				parts := strings.SplitN(line, ":", 2)
				if len(parts) == 2 {
					key := strings.TrimSpace(parts[0])
					value := strings.TrimSpace(parts[1])
					// 移除可能的引号
					value = strings.Trim(value, "'\"")
					result[key] = value
				}
			}
		}
	}

	return result
}
